package com.tjx.utils;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * 订单编号生成工具类（支持分布式、高并发）
 */
@Component
public class OrderNoGenerator {

    // 订单前缀（可自定义，如ORD=订单、TKT=门票、PKG=套餐）
    private static final String ORDER_PREFIX = "ORD";
    // 日期格式（年月日）
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
    // 自增序号位数（4位：0001-9999，可改为6位支持更大并发）
    private static final int SEQUENCE_LENGTH = 4;
    // Redis 键前缀（按日期存储自增序列）
    private static final String REDIS_KEY_PREFIX = "order:sequence:";

    private final StringRedisTemplate redisTemplate;

    // 构造注入 Redis 模板
    public OrderNoGenerator(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 生成订单编号
     */
    public String generateOrderNo() {
        // 1. 生成日期部分（如20241003）
        String dateStr = LocalDate.now().format(DATE_FORMATTER);

        // 2. 生成 Redis 键（按日期区分，每日重置序号）
        String redisKey = REDIS_KEY_PREFIX + dateStr;

        // 3. 原子自增获取序号（Redis INCR 保证并发安全，初始值1）
        Long sequence = redisTemplate.opsForValue().increment(redisKey, 1);

        // 4. 设置 Redis 键过期时间（2天，避免垃圾数据）
        redisTemplate.expire(redisKey, 2, TimeUnit.DAYS);

        // 5. 序号补零（不足4位补0，如1→0001）
        String sequenceStr = String.format("%0" + SEQUENCE_LENGTH + "d", sequence);

        // 6. 拼接订单编号（前缀+日期+序号）
        return ORDER_PREFIX + dateStr + sequenceStr;
    }
}